﻿using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace InnerProduct
{
    public class ColorHSV
    {
        public double H { get; set; }
        public double S { get; set; }
        public double V { get; set; }
        public byte A { get; set; }

        public ColorHSV()
        {
            H = 0; S = 0; V = 1.0; A = 255;
        }

        public ColorHSV(double h, double s, double v)
        {
            H = h; S = s; V = v; A = 255;
        }

        public ColorHSV Clone()
        {
            return new ColorHSV(H, S, V) { A = this.A };
        }

        public Color Color
        {
            get
            {
                double R = 0, G = 0, B = 0;

                if (V == 0)
                {
                    R = 0; G = 0; B = 0;
                }
                else if (S == 0)
                {
                    R = V;
                    G = V;
                    B = V;
                }
                else
                {
                    var hf = (H % 360.0) / 60.0;
                    var i = Convert.ToUInt32(Math.Floor(hf));
                    var f = hf - i;
                    var pv = V * (1 - S);
                    var qv = V * (1 - S * f);
                    var tv = V * (1 - S * (1 - f));
                    switch (i)
                    {
                        case 0:
                            R = V;
                            G = tv;
                            B = pv;
                            break;
                        case 1:
                            R = qv;
                            G = V;
                            B = pv;
                            break;
                        case 2:
                            R = pv;
                            G = V;
                            B = tv;
                            break;
                        case 3:
                            R = pv;
                            G = qv;
                            B = V;
                            break;
                        case 4:
                            R = tv;
                            G = pv;
                            B = V;
                            break;
                        case 5:
                            R = V;
                            G = pv;
                            B = qv;
                            break;
                        default:
                            break;
                    }
                }
                R *= 255.0;
                G *= 255.0;
                B *= 255.0;

                return Color.FromArgb(A, Convert.ToByte(R), Convert.ToByte(G), Convert.ToByte(B));
            }
            set
            {
                A = value.A;
                int x = Math.Min(value.R, Math.Min(value.G, value.B));
                int v = Math.Max(value.R, Math.Max(value.G, value.B));
                V = v / 255.0;
                if (v == x)
                {
                    H = 0; S = 0;
                    return;
                }
                S = (double)(v - x) / v;
                double f, i;
                if (x == value.R)
                {
                    f = value.G - value.B;
                    i = 3;
                }
                else if (x == value.G)
                {
                    f = value.B - value.R;
                    i = 5;
                }
                else
                {
                    f = value.R - value.G;
                    i = 1;
                }
                H = (i - f / (v - x)) * 60;
            }
        }
    }
}
